package com.demo.aidlproject.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import com.demo.aidlproject.ConnectionListener;
import com.demo.aidlproject.IMessageService;
import com.demo.aidlproject.IServiceManager;
import com.demo.aidlproject.MessageReciverLister;
import com.demo.aidlproject.aidl.IConnectionService;
import com.demo.aidlproject.entity.ConnectInfo;
import com.demo.aidlproject.entity.MessageBean;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class RemoteService extends Service {
    public static final String TAG=RemoteService.class.getSimpleName();
    private  ScheduledExecutorService scheduledExecutorService;
    private  ScheduledFuture scheduledFuture;
    private RemoteCallbackList<MessageReciverLister> remoteCallbackList =new RemoteCallbackList<>();
    private boolean isConnected=false;
    private Handler handler=new Handler(Looper.getMainLooper());
    public RemoteService() {
        Log.e(TAG, "RemoteService:construct " );
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate: " );
        scheduledExecutorService=new ScheduledThreadPoolExecutor(1);
    }
    private void timer(){
        Log.e(TAG, "timer: " );
        scheduledFuture=scheduledExecutorService.scheduleAtFixedRate(() -> sendMessageToMain(),1000,1000, TimeUnit.MILLISECONDS);
    }
    private void sendMessageToMain(){
        int size=remoteCallbackList.beginBroadcast();
        Log.e(TAG, "sendMessageToMain: size=="+size );
        for (int i = 0; i < size; i++) {
            MessageBean messageBean =new MessageBean();
            messageBean.setContent("this message from remote service");
            try {
                remoteCallbackList.getBroadcastItem(i).onMessageReciver(messageBean);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            remoteCallbackList.finishBroadcast();
        }
    }
    IServiceManager iServiceManager=new IServiceManager.Stub() {
        @Override
        public IBinder getService(String serviceName) throws RemoteException {
            Log.e(TAG, "getService: "+serviceName );
            if (IConnectionService.class.getSimpleName().equals(serviceName)) {
                return iConnectionService.asBinder();
            }else if (IMessageService.class.getSimpleName().equals(serviceName)){
                return iMessageService.asBinder();
            }
            return null;
        }
    };
    private void connectCallBack(ConnectionListener connectionListener){
        if (connectionListener!=null) {
            Log.e(TAG, "connect: lister=="+connectionListener );
            RemoteCallbackList<ConnectionListener> remoteCallbackList =new RemoteCallbackList<>();
            remoteCallbackList.register(connectionListener);
            int size=remoteCallbackList.beginBroadcast();
            Log.e(TAG, "connect: size=="+size );
            for (int i = 0; i < size; i++) {
                try {
                    ConnectInfo connectInfo=new ConnectInfo();
                    connectInfo.setState("success remote");
//                    connectionListener.connectSuccess(connectInfo);
                    remoteCallbackList.getBroadcastItem(i).connectSuccess(connectInfo);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            remoteCallbackList.finishBroadcast();

        }else{
            Log.e(TAG, "connect: lister==null" );
        }
    }
    private IConnectionService iConnectionService=new IConnectionService.Stub() {

        @Override
        public void connect(ConnectionListener connectionListener) throws RemoteException {
            Log.e(TAG, "connect: "+Thread.currentThread().getName() );
            try {
                Thread.sleep(1000);
                connectCallBack(connectionListener);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isConnected=true;
            // 连接成功后开启定时器
            timer();
        }

        @Override
        public void disconnect() throws RemoteException {
            isConnected=false;
            scheduledFuture.cancel(true);
        }

        @Override
        public boolean isConnected() throws RemoteException {
            return isConnected;
        }
    };
    IMessageService iMessageService=new IMessageService.Stub() {
        @Override
        public void sendMessage(MessageBean message) throws RemoteException {
            Log.e(TAG, "sendMessage: "+message.toString() );
        }

        @Override
        public void registerMessageReceiverListener(MessageReciverLister messageReciverLister) throws RemoteException {
            Log.e(TAG, "registerMessageReceiverListener: " );
            if (messageReciverLister!=null){
                remoteCallbackList.register(messageReciverLister);
            }

        }

        @Override
        public void unRegisterMessageReceiverListener(MessageReciverLister messageReciverLister) throws RemoteException {
            Log.e(TAG, "unRegisterMessageReceiverListener: " );
            if (messageReciverLister!=null){
                remoteCallbackList.unregister(messageReciverLister);
            }
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
//        return iConnectionService.asBinder();
        Log.e(TAG, "onBind: " );
        return iServiceManager.asBinder();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand: " );
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onRebind(Intent intent) {
        Log.e(TAG, "onRebind: " );
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: " );
    }
}